<template>
  <view class="pricke">
    <uni-transition
      v-if="mark"
      ref="aniMark"
      custom-class="transition"
      mode-class="fade"
      :styles="stylesMark"
      :show="show"
      @click="clickMark"
    ></uni-transition>
    <uni-transition ref="ani" custom-class="transition" :mode-class="modeClass" :styles="styles" :show="show">
      <view class="m-picker">
        <view
          class="m-picker__case"
          :style="{
            background: bgColor,
            borderTopLeftRadius: radius[0] + 'rpx',
            borderTopRightRadius: radius[1] + 'rpx',
            borderBottomLeftRadius: radius[2] + 'rpx',
            borderBottomRightRadius: radius[3] + 'rpx',
            paddingBottom: model == 'bottom' ? 'calc(constant(safe-area-inset-bottom) + 30rpx)' : '30rpx',
            paddingBottom: model == 'bottom' ? 'calc(env(safe-area-inset-bottom) + 30rpx)' : '30rpx',
          }"
        >
          <slot v-if="model == 'bottom'" name="handle">
            <view class="handle">
              <view class="button cancel" :style="cancelStyle" @click="cancel">{{ cancelText }}</view>
              <view class="button confirm" :style="confirmStyle" @click="confirm">{{ confirmText }}</view>
            </view>
          </slot>
          <slot>
            <view class="content" :style="{ height: `${height}rpx` }">
              <picker-view
                class="picker-view"
                :indicator-class="indicatorClass"
                :indicator-style="indicatorStyle"
                :value="pickerValue"
                @change="bindChange"
                @pickstart="pickstart"
                @pickend="pickend"
              >
                <picker-view-column v-for="(rangeItem, rangeIndex) in range" :key="rangeIndex">
                  <view class="picker-view__item" v-for="(item, index) in rangeItem" :key="index">
                    {{ item[rangeKey] }}
                  </view>
                </picker-view-column>
              </picker-view>
            </view>
          </slot>
          <slot v-if="model != 'bottom'" name="handle">
            <view class="handle">
              <view class="button cancel" :style="cancelStyle" @click="cancel">{{ cancelText }}</view>
              <view class="button confirm" :style="confirmStyle" @click="confirm">{{ confirmText }}</view>
            </view>
          </slot>
        </view>
      </view>
    </uni-transition>
  </view>
</template>

<script>
/**
 * PickerPopup 弹窗滚动选择器
 * @property {Boolean} mark = [true|false] 是否显示遮罩
 * @property {Boolean} markClose = [true|false] 点击遮罩是否关闭
 * @property {Boolean} btnClose = [true|false] 点击按钮是否关闭
 * @property {Boolean} show = [true|false] 是否显示弹窗
 * @property {Array} range 数据
 * @property {String} rangeKey picker-item显示内容的key, 默认 label
 * @property {String} indicatorStyle 设置选择器中间选中框的样式
 * @property {String} indicatorClass 设置选择器中间选中框的类名，注意页面或组件的style中写了scoped时，需要在类名前写/deep/
 * @property {String} cancelText cancel文字
 * @property {String} confirmText confirm文字
 * @property {Object} cancelStyle cancel样式style
 * @property {Object} confirmStyle cancel样式style
 * @property {Number} height 内容高度 rpx
 * @property {Number} borderRadius 圆角 rpx
 * @property {String} bgColor 背景颜色
 * @property {String} markBgColor mark 背景颜色
 * @property {String} mode 方向 top/bottom/center
 *
 * @event {Function} cancel 点击取消按钮
 * @event {Function} confirm 点击确认按钮
 */
export default {
  name: 'JarvisPicker',
  props: {
    // 是否显示遮罩
    mark: {
      type: Boolean,
      default: true,
    },
    // 点击遮罩是否关闭
    markClose: {
      type: Boolean,
      default: true,
    },
    // 点击按钮是否关闭
    btnClose: {
      type: Boolean,
      default: true,
    },
    // 是否显示弹窗
    show: {
      type: Boolean,
      default: false,
    },
    // 数据
    range: {
      type: Array,
      default: () => [],
    },
    // picker-item显示内容的key
    rangeKey: {
      type: String,
      default: 'label',
    },
    // 设置选择器中间选中框的样式
    indicatorStyle: {
      type: String,
      default: 'height: 50px;',
    },
    // 设置选择器中间选中框的类名，注意页面或组件的style中写了scoped时，需要在类名前写/deep/
    indicatorClass: {
      type: String,
      default: '',
    },
    // cancel文字
    cancelText: {
      type: String,
      default: '取消',
    },
    // confirm文字
    confirmText: {
      type: String,
      default: '确定',
    },
    // cancel样式style
    cancelStyle: {
      type: Object,
      default: () => ({}),
    },
    // confirm样式style
    confirmStyle: {
      type: Object,
      default: () => ({}),
    },
    // 内容高度 rpx
    height: {
      type: Number,
      default: 500,
    },
    // 圆角 rpx
    borderRadius: {
      type: Number,
      default: 16,
    },
    // 背景颜色
    bgColor: {
      type: String,
      default: '#FFFFFF',
    },
    // mark 背景颜色
    markBgColor: {
      type: String,
      default: '#00000080',
    },
    // 方向 top/bottom/center
    mode: {
      type: String,
      default: 'bottom',
    },
  },
  data() {
    return {
      pickerValue: [], // 选中的索引
      isScoll: false, // 是否正在滚动
    }
  },
  computed: {
    model() {
      if (this.mode == 'top') return 'top'
      else if (this.mode == 'bottom') return 'bottom'
      else if (this.mode == 'center') return 'center'
      else return 'bottom'
    },
    stylesMark() {
      return {
        position: 'fixed',
        top: 0,
        left: 0,
        right: 0,
        bottom: 0,
        zIndex: 99,
        backgroundColor: this.markBgColor,
      }
    },
    styles() {
      const top = {
        position: 'fixed',
        left: 0,
        right: 0,
        top: 0,
        zIndex: 100,
      }
      const bottom = {
        position: 'fixed',
        left: 0,
        right: 0,
        bottom: 0,
        zIndex: 100,
      }
      const center = {
        position: 'fixed',
        left: '50%',
        top: '50%',
        width: '90vw',
        transform: 'translate(-50%, -50%)',
        zIndex: 100,
      }
      if (this.model == 'top') return top
      else if (this.model == 'bottom') return bottom
      else if (this.model == 'center') return center
      else return bottom
    },
    radius() {
      const borderRadius = this.borderRadius
      if (this.model == 'top') return [0, 0, borderRadius, borderRadius]
      else if (this.model == 'bottom') return [borderRadius, borderRadius, 0, 0]
      else if (this.model == 'center') return [borderRadius, borderRadius, borderRadius, borderRadius]
      else return [0, 0, 0, 0]
    },
    modeClass() {
      if (this.model == 'top') return ['fade', 'slide-top']
      else if (this.model == 'bottom') return ['fade', 'slide-bottom']
      else if (this.model == 'center') return 'fade'
      else return ['fade', 'slide-bottom']
    },
  },
  watch: {
    range(val) {
      if (val.length) {
        let arr = []
        for (let index in this.range) {
          arr.push(0)
        }
        this.pickerValue = arr
      }
    },
  },
  created() {
    if (this.range && this.range.length) {
      this.pickerValue = []
      for (let index in this.range) {
        this.pickerValue.push(0)
      }
    }
  },
  methods: {
    /**
     * 关闭
     */
    close() {
      if (!this.isScoll) this.$emit('update:show', false)
    },
    /**
     * 取消
     */
    cancel() {
      this.$emit('cancel')
      if (this.btnClose) this.close()
    },
    /**
     * 确定
     */
    confirm() {
      // 滚动结束后才能点击
      if (!this.isScoll) {
        this.$emit('confirm', this.pickerValue)
        if (this.btnClose) this.close()
      }
    },
    /**
     * 点击遮罩
     */
    clickMark() {
      if (this.markClose) this.close()
    },
    /**
     * picker-view 改变
     * @param {Object} e
     */
    bindChange(e) {
      const val = e.detail.value
      this.pickerValue = val
    },
    /**
     * picker-view开始滚动
     */
    pickstart() {
      this.isScoll = true
    },
    /**
     * picker-view 滚动结束
     */
    pickend() {
      this.isScoll = false
    },
  },
}
</script>

<style lang="scss">
.m-picker {
  width: 100%;
  height: 100%;

  &__case {
    padding-left: 56rpx;
    padding-right: 56rpx;
    padding-top: 30rpx;
    padding-bottom: 30rpx;

    .handle {
      width: 100%;
      display: flex;
      align-items: center;
      justify-content: space-between;

      .button {
        font-size: 32rpx;
        font-family: PingFang SC;
        color: #000000;
      }
    }

    .content {
      width: 100%;
      height: 400rpx;
    }
  }
}

.picker-view {
  width: 100%;
  height: 100%;

  &__item {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 48rpx;
  }
}
</style>
